home *** CD-ROM | disk | FTP | other *** search
Wrap
/* File: Test.c Contains: xxx put contents here xxx Written by: Kevin Arnold - based on sample code from Nav services written by Tony Bacigalupi Copyright: © 1998 - 1999 by Apple Computer, Inc., all rights reserved. Change History (most recent first): <16> 03-24-99 KA converting to new headers <15> 03-22-99 KA converting to new data type names (ie NSLxxx) and handle NSLStandardGetURL returning OSStatus <14> 02-23-99 KA added parameter to the NSLGetStandardURL call <13> 02-05-99 KA added async calling to NSL <12> 01-12-99 KA put back reference to NSLStandardGetURL and use new parsing pb call <11> 12-15-98 KA removed reference to NSLStandardGetURL <10> 11-05-98 KA removed reference to NSLStandardURL.h <09> 10-20-98 KA fixed bug in non-fatal error handling <08> 10-15-98 KA added showURLTEField param option <06> 10/08/98 KA added filter proc param to NSLStandardGetURL call <05> 8/25/98 KA we weren't setting done to false in the beginning of TestSyncServicesLookup <04> 8/12/98 KA added cleanup calls to free our NSL made objects <03> 7/21/98 KA added NSLErrorToString calls <01> 4/06/98 KA Initial check-in. To Do: */ #include "NSL.h" #if PROFILE #include <Profiler.h> #endif #include <StdIO.h> #include <string.h> #include <Threads.h> #ifdef __MWERKS__ #include <SIOUX.h> #endif #define kWebServerType "http" #define kFTPServerType "ftp" #define kAppleShareType "AFPServer" #define kLaserWriterType "LaserWriter" NSLClientRef gOurClientRef; char gErrorString[256]; char gSolutionString[256]; void TestDefaultNeighborhoodLookup( void ); void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood ); void TestSyncServicesLookup( char* service ); void TestAsyncServicesLookup( char* service ); void TestStandardRegisterURL(void); void TestStandardDeregisterURL(void); void DoNSLFatalAlert( NSLError theError ); void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch ); static char GetPressedKey() { char c; char dummy; scanf("%c%c", &c, &dummy); return c; } void DoNSLFatalAlert( NSLError theError ) { char errorString[256]; char solutionString[256]; // call this if you don't want to give the user the option of canceling the search NSLErrorToString( theError, errorString, solutionString ); printf( "Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString ); } void DoNSLNonFatalAlert( NSLError theError, Boolean* cancelSearch ) { char errorString[256]; char solutionString[256]; char result; // call this if the error isn't fatal and the user might want to continue/cancel the search NSLErrorToString( theError, errorString, solutionString ); printf( "Non Fatal error occurred: %ld\r%s\r%s\r", theError.theErr, errorString, solutionString ); printf( "Press Y to continue or N to cancel" ); result = GetPressedKey(); if ( result == 'y' || result == 'Y' ) *cancelSearch = false; else *cancelSearch = true; } void main() { OSStatus status; Boolean quit = false; Boolean doBanner = true; Ptr url; NSLDialogOptions options; // NSLEventUPP eventUPP = NewNSLEventUPP(OurEventHandler); #ifdef __MWERKS__ SIOUXSettings.asktosaveonclose = 0; #endif #if PROFILE ProfilerInit(collectDetailed, bestTimeBase, 500, 20); #endif printf("NSL API Test\rGenerated %s at %s\r\r", __DATE__, __TIME__); status = NSLOpenNavigationAPI( &gOurClientRef ); if ( status && status != kNSLSomePluginsFailedToLoad ) printf("NSLAPI could not be opened due to an internal error\r"); else { if ( status == kNSLSomePluginsFailedToLoad ) { // this isn't a fatal error, so we want to let someone know but we will continue. NSLError cludgeError; // we have to crock one as this is the only time we will get back an OSStatus // instead of an NSLError. Just make theContext be zero cludgeError.theErr = status; cludgeError.theContext = 0; NSLErrorToString( cludgeError, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", cludgeError.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } do { char c; if ( doBanner ) printf("\r\r\rPlease make a choice [1-6 and hit return]:\r\t1 - Get list of Default Neighborhoods available\r\t2 - Get list of Webservers in a Neighborhood(sync)\r\t3 - Get list of Webservers in a Neighborhood(async)\r\t4 - Get list of AppleShare servers in a Neighborhood\r\t5 - Browse for url\r\t6 - QUIT\r\r> "); c = GetPressedKey(); doBanner = true; switch ( c) { case '1': TestDefaultNeighborhoodLookup(); break; case '2': TestSyncServicesLookup(kWebServerType); break; case '3': TestAsyncServicesLookup(kWebServerType); break; case '4': TestSyncServicesLookup(kAppleShareType); break; case '5': NSLGetDefaultDialogOptions( &options ); status = NSLStandardGetURL( &options, nil, nil, nil, "Web,http,https;FTP,ftp;AppleShare,AFPServer,afp;", &url ); if ( status == noErr ) { printf( "\rURL Returned: %s\r", url ); url = NSLFreeURL( url ); } else if ( status == kNSLUserCanceled ) printf( "\rUser Canceled URL Selection\r"); else printf( "\rNSLStandardGetURL returned: %ld", status ); break; case '6': printf("Bye now!\r"); quit = true; break; default: doBanner = false; } } while ( quit == false ); } #if PROFILE ProfilerDump("\pPerformances"); ProfilerTerm(); #endif ExitToShell(); } #define kBufferLength 4096 void TestDefaultNeighborhoodLookup( void ) { NSLNeighborhood neighborhood; printf( "Getting default NSLNeighborhoods\r\r" ); neighborhood = NSLMakeNewNeighborhood( "", NULL ); // empty string for default neighborhood lookup, NULL for empty protocol string // meaning we want all default neighborhoods TestSyncNeighborhoodLookup( neighborhood ); NSLFreeNeighborhood( neighborhood ); // make sure we free up this memory } void TestSyncNeighborhoodLookup( NSLNeighborhood neighborhood ) { char tempName[256]; long bufLen = kBufferLength; char* buffer = NULL; char* tempPtr = NULL; NSLRequestRef ourRequestRef; NSLClientAsyncInfoPtr ourAsyncInfo; NSLError iErr = kNSLErrorNoErr; NSLNeighborhood nhPtr = NULL; long nhLength, tempPtrLength; Boolean done = false; printf( "Looking up Neighborhoods\r\r" ); buffer = NewPtr( bufLen ); // first prepare the request which will set up a NSLClientAsyncInfoPtr for us iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo ); if ( iErr.theErr ) { printf("NSLPrepareRequest returned error %ld\r", iErr.theErr ); NSLErrorToString( iErr, gErrorString, gSolutionString ); printf("Error: %s\r", gErrorString ); printf("Solution: %s\r", gSolutionString ); } // set the values of ourAsyncInfo pb ourAsyncInfo->clientContextPtr = NULL; ourAsyncInfo->maxSearchTime = 0; // no max search time ourAsyncInfo->alertInterval = 0; // no alert interval ourAsyncInfo->alertThreshold = 1; // make alert threshold every item... if ( iErr.theErr == noErr ) iErr = NSLStartNeighborhoodLookup( ourRequestRef, neighborhood, ourAsyncInfo ); do { if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 ) { while ( NSLGetNextNeighborhood( ourAsyncInfo, &nhPtr, &nhLength ) ) { if ( nhLength > 0 && nhLength < kBufferLength ) { NSLGetNameFromNeighborhood( nhPtr, &tempPtr, &tempPtrLength ); memcpy( tempName, tempPtr, tempPtrLength ); tempName[tempPtrLength] = '\0'; printf( "%s\r", tempName ); } } } if ( ourAsyncInfo->searchState == kNSLSearchStateComplete ) done = true; else if ( iErr.theErr == noErr ) iErr = NSLContinueLookup( ourAsyncInfo ); } while ( !iErr.theErr && !done ); if ( iErr.theErr ) { NSLErrorToString( iErr, gErrorString, gSolutionString ); printf("Error: %s\r", gErrorString ); printf("Solution: %s\r", gSolutionString ); } if ( buffer ) DisposePtr(buffer); } void TestSyncServicesLookup( char* service ) { char name[256] = "\p"; char url[1024]; long bufLen = kBufferLength; char* buffer = NewPtr( bufLen ); NSLRequestRef ourRequestRef; NSLClientAsyncInfoPtr ourAsyncInfo; NSLError iErr = kNSLErrorNoErr; NSLServicesList serviceList = NULL; NSLTypedDataPtr newDataPtr = NULL; NSLNeighborhood neighborhood, urlPtr = NULL; long urlLength; Boolean done = false; char c; printf( "Please Type in the neighborhood you want to search then hit return\r" ); scanf("%c", &c ); while ( c != '\r' && c != '\n' && name[0] < 256 ) { name[0]++; name[name[0]] = c; scanf("%c", &c ); }; p2cstr( (unsigned char*)name ); neighborhood = NSLMakeNewNeighborhood( name, NULL ); printf( "Looking up Service\r\r" ); // first prepare the request which will set up a NSLClientAsyncInfoPtr for us iErr = NSLPrepareRequest( NULL, NULL, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo ); if ( iErr.theErr ) { printf("NSLPrepareRequest returned error %ld\r", iErr.theErr ); NSLErrorToString( iErr, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", iErr.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } else { serviceList = NSLMakeNewServicesList( service ); // we can pass a comma delimited cstring here (ie "http,ftp") // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish if ( serviceList != NULL ) { iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr ); // we can also pass an attribute if we want to get more specific NSLDisposeServicesList( serviceList ); // we are done with this, free this memory! } // set the values of ourAsyncInfo pb ourAsyncInfo->clientContextPtr = NULL; ourAsyncInfo->maxSearchTime = 0; // no max search time ourAsyncInfo->alertInterval = 0; // no alert interval ourAsyncInfo->alertThreshold = 1; // make alert threshold every item... if ( iErr.theErr == noErr ) iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo ); do { if ( iErr.theErr == noErr && ourAsyncInfo->totalItems > 0 ) { while ( NSLGetNextUrl( ourAsyncInfo, &urlPtr, &urlLength ) ) { if ( urlLength > 0 ) { memcpy( url, urlPtr, urlLength ); url[urlLength] = '\0'; printf( "%s\r", url ); } } } else if ( iErr.theErr ) { NSLErrorToString( iErr, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", iErr.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } if ( ourAsyncInfo->searchState == kNSLSearchStateComplete ) done = true; else iErr = NSLContinueLookup( ourAsyncInfo ); // if search state isn't complete, then the error wasn't fatal } while ( !done ); // it is possible to get errors back, but if the search state isn't complete, then one or more // plugins are still working! NSLFreeTypedDataPtr( newDataPtr ); // dispose this } NSLFreeNeighborhood( neighborhood ); // make sure we free up this memory if ( buffer ) DisposePtr(buffer); } typedef struct { NSLRequestRef theRequestRef; NSLTypedDataPtr theRequestDataPtr; Boolean lookupFinished; } LookupContext, *LookupContextPtr; pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr ); pascal void ServicesLookupNotifyProc( NSLClientAsyncInfoPtr nslInfoPtr ) { LookupContextPtr lookupContext = (LookupContextPtr)nslInfoPtr->clientContextPtr; char* curURL; char* urlPtr = NULL; NSLError nslError; long urlLength; Boolean weDone = false, cancelSearch = false;; // first check our ptrs and to see if this is from the current request if ( nslInfoPtr && lookupContext ) { // we might want to think about putting up an alert message here if we have received one... if ( nslInfoPtr->searchResult.theErr ) { if ( nslInfoPtr->searchState != kNSLSearchStateComplete ) { DoNSLNonFatalAlert( nslInfoPtr->searchResult, &cancelSearch ); } else { DoNSLFatalAlert( nslInfoPtr->searchResult ); // user has no choice cancelSearch = true; } } if ( nslInfoPtr->totalItems > 0 && !cancelSearch ) { while ( NSLGetNextUrl( nslInfoPtr, &urlPtr, &urlLength ) ) { if ( urlLength > 0 ) { curURL = NewPtr( urlLength + 1 ); // The NSL Manager WON'T call us at interrupt time so mem aloocation is OK! BlockMove( urlPtr, curURL, urlLength ); curURL[urlLength] = '\0'; // null terminate! } else { weDone = true; } if ( !weDone ) { printf( "%s\r", curURL ); } if ( curURL ) DisposePtr( curURL ); // now we could just have curURL be on the stack in this case but to show that // memory allocation is cool in the notifier we did it this way... curURL = NULL; } } if ( !cancelSearch && nslInfoPtr->searchState != kNSLSearchStateComplete ) { nslError = NSLContinueLookup(nslInfoPtr); // don't forget to call NSLContinueLookup when you are done with the data in the buffer! if ( nslError.theErr ) { if ( nslInfoPtr->searchState != kNSLSearchStateComplete ) { DoNSLNonFatalAlert( nslError, &cancelSearch ); } else { DoNSLFatalAlert( nslError ); // user has no choice cancelSearch = true; } } } if ( !cancelSearch && nslInfoPtr->searchState == kNSLSearchStateComplete ) { lookupContext->lookupFinished = true; nslError = NSLDeleteRequest( lookupContext->theRequestRef ); if ( nslError.theErr ) DoNSLFatalAlert( nslError ); // user has no choice } else if ( cancelSearch ) // user decided error was bad enough to cancel the entire search { lookupContext->lookupFinished = true; nslError = NSLCancelRequest( lookupContext->theRequestRef ); if ( nslError.theErr == noErr ) nslError = NSLDeleteRequest( lookupContext->theRequestRef ); } } } void TestAsyncServicesLookup( char* service ) { char name[256] = "\p"; long bufLen = kBufferLength; char* buffer = NewPtr( bufLen ); LookupContextPtr contextPtr; NSLRequestRef ourRequestRef; NSLClientAsyncInfoPtr ourAsyncInfo; NSLError iErr = kNSLErrorNoErr; NSLServicesList serviceList = NULL; NSLTypedDataPtr newDataPtr = NULL; NSLNeighborhood neighborhood, urlPtr = NULL; Boolean done = false; char c; printf( "Please Type in the neighborhood you want to search then hit return\r" ); scanf("%c", &c ); while ( c != '\r' && c != '\n' && name[0] < 256 ) { name[0]++; name[name[0]] = c; scanf("%c", &c ); }; p2cstr( (unsigned char*)name ); neighborhood = NSLMakeNewNeighborhood( name, NULL ); printf( "Looking up Service\r\r" ); // first prepare the request which will set up a NSLClientAsyncInfoPtr for us contextPtr = NewPtr( sizeof( LookupContext ) ); if ( !contextPtr ) { printf( "NewPtr call failed!" ); return; } iErr = NSLPrepareRequest( ServicesLookupNotifyProc, contextPtr, gOurClientRef, &ourRequestRef, buffer, bufLen, &ourAsyncInfo ); if ( iErr.theErr ) { printf("NSLPrepareRequest returned error %ld\r", iErr.theErr ); NSLErrorToString( iErr, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", iErr.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } else { contextPtr->theRequestRef = ourRequestRef; contextPtr->theRequestDataPtr = ourAsyncInfo; contextPtr->lookupFinished = false; serviceList = NSLMakeNewServicesList( service ); // we can pass a comma delimited cstring here (ie "http,ftp") // now we need to create a NSLTypedDataPtr which holds teh serviceList info as well as an attribute if we wish if ( serviceList != NULL ) { iErr.theErr = NSLMakeServicesRequestPB( serviceList, &newDataPtr ); // we can also pass an attribute if we want to get more specific NSLDisposeServicesList( serviceList ); // we are done with this, free this memory! } // set the values of ourAsyncInfo pb ourAsyncInfo->maxSearchTime = 0; // no max search time ourAsyncInfo->alertInterval = 0; // no alert interval ourAsyncInfo->alertThreshold = 1; // make alert threshold every item... if ( iErr.theErr == noErr ) iErr = NSLStartServicesLookup( ourRequestRef, neighborhood, newDataPtr, ourAsyncInfo ); if ( iErr.theErr == noErr ) { while ( !contextPtr->lookupFinished ) { YieldToAnyThread(); // its important to have a call to YieldToAnyThread in your main event loop // which is what we are simulating here... SystemTask(); } } NSLFreeTypedDataPtr( newDataPtr ); // dispose this } NSLFreeNeighborhood( neighborhood ); // make sure we free up this memory if ( buffer ) DisposePtr(buffer); } // the code below is provided as an example, but won't work here because we don't have an event loop // that calls YieldToAnyThread. void TestStandardRegisterURL(void) { char url[1024]; UInt16 index = 0; NSLError regError; char c; printf( "Please Type in the url you want to register then hit return\r" ); scanf("%c", &c ); while ( c != '\r' && c != '\n' && index < sizeof(url)-1 ) { url[index++] = c; scanf("%c", &c ); }; url[index] = '\0'; // null terminate this regError = NSLStandardRegisterURL( url, nil ); // we aren't going to specify a neighborhood to register in, leave it up to the plugins if ( regError.theErr ) { NSLErrorToString( regError, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", regError.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } else printf("URL registered"); } void TestStandardDeregisterURL(void) { char url[1024]; UInt16 index = 0; NSLError regError; char c; printf( "Please Type in the url you want to register then hit return\r" ); scanf("%c", &c ); while ( c != '\r' && c != '\n' && index < sizeof(url)-1 ) { url[index++] = c; scanf("%c", &c ); }; url[index] = '\0'; // null terminate this regError = NSLStandardDeregisterURL( url, nil ); // we aren't going to specify a neighborhood to deregister in, leave it up to the plugins if ( regError.theErr ) { NSLErrorToString( regError, gErrorString, gSolutionString ); printf("Error #%ld: %s\r", regError.theErr, gErrorString ); printf("Solution: %s\r", gSolutionString ); } else printf("URL deregistered"); }